package org.scohen.juploadr;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 
 */

class SortedProperties extends Properties {
    private Map<Object, Object> backingStore = new LinkedHashMap<Object, Object>();

    public SortedProperties() {
    }

    public String getProperty(String key, String defaultValue) {
        String val = (String) backingStore.get(key);
        if (val == null) {
            val = defaultValue;
        }
        return val;
    }

    public String getProperty(String key) {
        return (String) backingStore.get(key);
    }

    public void list(PrintStream out) {
        // TODO Auto-generated method stub
        super.list(out);
    }

    public void list(PrintWriter out) {
        // TODO Auto-generated method stub
        super.list(out);
    }

    public synchronized void load(InputStream inStream) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
        String line;
        while ((line = in.readLine()) != null) {
            if (line.endsWith("\\")) {
                line = line.concat("\n" + in.readLine());
            }
            String[] parts = line.split("=");

            if (parts.length == 2) {

                backingStore.put(parts[0], parts[1]);
            } else if (line.trim().length() > 0) {
                System.out.println("bad: " + line);
            }
        }
    }

    public Enumeration<?> propertyNames() {
        return new Enumeration() {
            private Iterator iter = backingStore.keySet().iterator();

            public boolean hasMoreElements() {
                return iter.hasNext();
            }

            public Object nextElement() {
                return iter.next();
            }
        };
    }

    public synchronized void save(OutputStream out, String header) {

        try {
            store(out, header);
        } catch (IOException e) {

        }

    }

    public synchronized Object setProperty(String key, String value) {
        return backingStore.put(key, value);
    }

    public void store(OutputStream o, String header) throws IOException {
        PrintWriter out = new PrintWriter(o);
        Iterator iter = backingStore.keySet().iterator();
        while (iter.hasNext()) {
            String key = (String) iter.next();
            if (backingStore.get(key) != null && key.trim().length() > 0) {
                out.print(key);
                out.print("=");
                out.print(backingStore.get(key).toString());
                out.println();
            }
        }
        out.println();
        out.flush();
        out.close();
    }

    public void clear() {

        backingStore.clear();
    }

    public boolean containsKey(Object key) {
        return backingStore.containsKey(key);
    }

    public boolean containsValue(Object value) {
        return backingStore.containsValue(value);
    }

    public Set<Map.Entry<Object,Object>> entrySet() {
        return backingStore.entrySet();
    }

    public boolean equals(Object o) {
        return backingStore.equals(o);
    }

    public Object get(Object key) {
        return backingStore.get(key);
    }

    public int hashCode() {
        return backingStore.hashCode();
    }

    public boolean isEmpty() {
        return backingStore.isEmpty();
    }

    public Set<Object> keySet() {
        return new LinkedHashSet<Object>(backingStore.keySet());
    }

    public Object put(Object key, Object value) {
        return backingStore.put(key, value);
    }

    public void putAll(Map<?,?> t) {
        backingStore.putAll(t);
    }

    public Object remove(Object key) {
        return backingStore.remove(key);
    }

    public int size() {
        return backingStore.size();
    }

    public Collection<Object> values() {
        return backingStore.values();
    }

}